<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    
  </style>
</head>
<body>
  
</body>
<script>

  // 1. 单例模式创建对象
  // const obj = {
  //   name: "admin",
  //   age: 18,
  //   show:function(){
  //     console.log("hello " + this.name)
  //   }
  // }

  // 2. 对单例模式进行封装，抽象相同属性或功能，类
  // function createObj(n, a){
  //   const obj = {
  //     name: n,
  //     age: a,
  //     show:function(){
  //       console.log("hello " + this.name)
  //     }
  //   }
  //   return obj
  // }
  // const o1 = createObj("admin", 18);
  // const o2 = createObj("zhangsan", 20);
  // console.log(o1);
  // console.log(o2);
  // console.log(o2 === o1);
  // o1.show()
  // o2.show()
  // console.log(o2.show === o1.show);

  // 3. 将相同的功能，再次抽象成公共接口规范
  // const f = {
  //   show:function(){
  //     console.log("hello " + this.name)
  //   }
  // }
  // function createObj(n, a){
  //   const obj = {
  //     name: n,
  //     age: a,
  //     ...f
  //   }
  //   return obj
  // }
  // const o1 = createObj("admin", 18);
  // const o2 = createObj("zhangsan", 20);
  // console.log(o1);
  // console.log(o2);
  // console.log(o2 === o1);
  // o1.show()
  // o2.show()
  // console.log(o2.show === o1.show);

  // 4. 将抽象出的接口规范和类进行高内聚
  // function createObj(n, a){
  //   // 原料
  //   const obj = {
  //     ...createObj.xxx
  //   }
  //   // 加工
  //   obj.name = n;
  //   obj.age = a;
  //   // 出厂
  //   return obj;
  // }
  // createObj.xxx = {
  //   show:function(){
  //     console.log("hello " + this.name)
  //   }
  // }
  // const o1 = createObj("admin", 18);
  // const o2 = createObj("zhangsan", 20);
  // console.log(o1);
  // console.log(o2);
  // console.log(o2 === o1);
  // o1.show()
  // o2.show()
  // console.log(o2.show === o1.show);

  // 5. 以上工厂模式，属于自定义工厂模式，被替换了
  // 被官方提供的内置工厂模式替换

  // function createObj(n, a){
  //   this.name = n;
  //   this.age = a;
  // }
  // createObj.prototype.show = function(){
  //   console.log("hello " + this.name + "今年" + this.age);
  // }
  // const o1 = new createObj("admin", 19)
  // const o2 = new createObj("张三", 23)
  // console.log(o1)
  // console.log(o2)
  // o1.show()
  // o2.show()
  // console.log(o2 === o1)
  // console.log(o2.show === o1.show)


  // new的原理
    // 1. 创建一个新对象
    // 2. 将原函数中的this指向该对象
    // 3. 新对象会继承写在函数的prototype身上的规范
    // 4. 执行原函数所有代码
    // 5. 检测原函数是否主动返回对象，如果没有，返回这个新对象


  // 6. ES6提供的工厂模式 - class
  class createObj{
    constructor(n, a){
      this.name = n;
      this.age = a;
    }
    show(){
      console.log("hello " + this.name + "今年" + this.age);
    }
  }
  const o1 = new createObj("admin", 19)
  const o2 = new createObj("张三", 23)
  console.log(o1)
  console.log(o2)
  o1.show()
  o2.show()
  console.log(o2 === o1)
  console.log(o2.show === o1.show)


  console.log( typeof createObj );




  
</script>
</html>